#include "map_process/image_loader.h"
#include <filesystem>
#include <algorithm>
#include <iostream>

namespace map_process
{

// 构造函数：初始化支持的图像扩展名列表
ImageLoader::ImageLoader()
{
    // 初始化支持的图像文件扩展名
    initializeSupportedExtensions();
}

// 析构函数：清理资源
ImageLoader::~ImageLoader()
{
    // 当前无需清理操作
}

// 初始化支持的图像扩展名列表
void ImageLoader::initializeSupportedExtensions()
{
    // 设置支持的图像格式：PNG、JPEG、BMP、TIFF
    supported_extensions_ = {".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".tif"};
}

// 从指定目录加载第一个图像文件
cv::Mat ImageLoader::loadFirstImage(const std::string& directory_path)
{
    // ========== 步骤1：验证目录存在性 ==========
    // 检查目录是否存在
    if (!std::filesystem::exists(directory_path)) {
        std::cerr << "错误：找不到目录 " << directory_path << std::endl;
        return cv::Mat();
    }

    // ========== 步骤2：遍历目录查找图像文件 ==========
    // 遍历目录中的所有条目，寻找第一个有效的图像文件
    for (const auto& entry : std::filesystem::directory_iterator(directory_path)) {
        // 只处理常规文件（跳过目录和符号链接）
        if (entry.is_regular_file()) {
            std::string file_path = entry.path().string();
            
            // ========== 步骤3：检查文件扩展名 ==========
            // 检查文件扩展名是否在支持的图像格式列表中
            if (isImageFile(file_path)) {
                // ========== 步骤4：验证文件存在性 ==========
                // 再次检查文件是否存在（防御性编程）
                if (!std::filesystem::exists(file_path)) {
                    std::cerr << "错误：找不到图像文件 " << file_path << std::endl;
                    continue;
                }

                // ========== 步骤5：使用OpenCV读取图像 ==========
                // 使用 OpenCV 读取图像文件
                // cv::imread 会自动处理不同格式的图像解码
                cv::Mat image = cv::imread(file_path);

                // ========== 步骤6：验证图像加载成功 ==========
                // 检查图像是否成功加载（空Mat表示加载失败）
                if (image.empty()) {
                    std::cerr << "错误：无法加载图像文件 " << file_path << std::endl;
                    continue;
                }

                // 成功加载，返回图像
                return image;
            }
        }
    }

    // 遍历完整个目录后仍未找到图像文件
    std::cerr << "错误：在目录 " << directory_path << " 中找不到图像文件" << std::endl;
    return cv::Mat();
}

cv::Mat ImageLoader::loadImage(const std::string& file_path)
{
    cv::Mat image = cv::imread(file_path);
    if (image.empty()) {
        std::cerr << "错误：无法加载图像文件 " << file_path << std::endl;
        return cv::Mat();
    }
    return image;
}

// 检查文件是否为支持的图像格式
bool ImageLoader::isImageFile(const std::string& file_path)
{
    // ========== 步骤1：提取文件扩展名 ==========
    // 从文件路径中提取扩展名（包括点号，如 ".png"）
    std::string extension = std::filesystem::path(file_path).extension().string();
    
    // ========== 步骤2：转换为小写 ==========
    // 将扩展名转换为小写，实现大小写不敏感的匹配
    std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);

    // ========== 步骤3：检查是否在支持列表中 ==========
    // 在支持的扩展名列表中查找匹配项
    return std::find(supported_extensions_.begin(), supported_extensions_.end(), extension) != supported_extensions_.end();
}

}  // namespace map_process